#include "MsgWnd.h"
#include "ui_MsgWnd.h"

#include "MainApp.h"

#include <QApplication>
#include <QDesktopWidget>
#include <QTimer>
#include <QEvent>
#include <QPainter>

#include "GlobalSignal.h"

#include "AppModel.h"

#define QUIT_TIME       10
#define LONG_QUIT_TIME  20
#define MAX_QUIT_TIME   30

MsgWnd* MsgWnd::g_msg_view = Q_NULLPTR;

void MsgWnd::ShowNormalInfo(const QString content1, const QString content2, const QString content3, QWidget* parent, bool modal)
{
    if (g_msg_view)
    {
        g_msg_view->showWnd(EMsgBoxType_NormalInfo, content1, content2, content3);
    }
    else
    {
        auto msgBox = new MsgWnd(EMsgBoxType_NormalInfo, parent, content1, content2, content3, modal);
        msgBox->show();

        g_msg_view = msgBox;
    }
}

void MsgWnd::ShowWaitInfo(const QString content1, const QString content2, const QString content3, QWidget* parent, bool modal)
{
    if (g_msg_view)
    {
        g_msg_view->showWnd(EMsgBoxType_ShowWait, content1, content2, content3);
    }
    else
    {
        auto msgBox = new MsgWnd(EMsgBoxType_ShowWait, parent, content1, content2, content3, modal);
        msgBox->show();

        g_msg_view = msgBox;
    }
}

void MsgWnd::ConfirmEraseExistSN(const QString content1, const QString content2, const QString content3, QWidget* parent, bool modal)
{
    if (g_msg_view)
    {
        g_msg_view->showWnd(EMsgBoxType_ConfirmEraseExistSN, content1, content2, content3);
    }
    else
    {
        auto msgBox = new MsgWnd(EMsgBoxType_ConfirmEraseExistSN, parent, content1, content2, content3, modal);
        msgBox->show();

        g_msg_view = msgBox;
    }
}

void MsgWnd::ConfirmDeleteActionRecord(const QString content1, const QString content2, const QString content3, QWidget* parent, bool modal)
{
    if (g_msg_view)
    {
        g_msg_view->showWnd(EMsgBoxType_ConfirmDelAction, content1, content2, content3);
    }
    else
    {
        auto msgBox = new MsgWnd(EMsgBoxType_ConfirmDelAction, parent, content1, content2, content3, modal);
        msgBox->show();

        g_msg_view = msgBox;
    }
}

void MsgWnd::ConfirmDeleteSNRecord(const QString content1, const QString content2, const QString content3, QWidget* parent, bool modal)
{
    if (g_msg_view)
    {
        g_msg_view->showWnd(EMsgBoxType_ConfirmDelSN, content1, content2, content3);
    }
    else
    {
        auto msgBox = new MsgWnd(EMsgBoxType_ConfirmDelSN, parent, content1, content2, content3, modal);
        msgBox->show();

        g_msg_view = msgBox;
    }
}

void MsgWnd::ScanInputNewSN(const QString content1, const QString content2, const QString content3, QWidget* parent, bool modal)
{
    if (g_msg_view)
    {
        g_msg_view->showWnd(EMsgBoxType_ScanInputNewSN, content1, content2, content3);
    }
    else
    {
        auto msgBox = new MsgWnd(EMsgBoxType_ScanInputNewSN, parent, content1, content2, content3, modal);
        msgBox->show();

        g_msg_view = msgBox;
    }
}

void MsgWnd::SendMsgMsgFail(const QString content1, const QString content2, const QString content3, QWidget* parent, bool modal)
{
    if (g_msg_view)
    {
        g_msg_view->showWnd(EMsgBoxType_SendMsgFail, content1, content2, content3);
    }
    else
    {
        auto msgBox = new MsgWnd(EMsgBoxType_SendMsgFail, parent, content1, content2, content3, modal);
        msgBox->show();

        g_msg_view = msgBox;
    }
}

MsgWnd::MsgWnd(EMsgBoxType type, QWidget *parent, QString content1, QString content2, QString content3, bool modal)
    :QWidget(parent)
    , ui(new Ui::MsgWnd)
    , parent_(parent)
    , type_(type)
    , content1_(content1)
    , content2_(content2)
    , content3_(content3)
    , timer_(new QTimer(this))
    , timer_cnt_(0)
    , timer_flag_(false)
{
    ui->setupUi(this);

    if (modal)
    {
        setAttribute(Qt::WA_ShowModal, true);
    }

    if (parent != Q_NULLPTR)
        parent_ = parent;
    else
        parent_ = MainApp::Instance()->GetBaseWidget();

    QRect container = parent_->geometry();
    QRect curPos = QRect(QPoint(0, 0), size());

    if (parent != Q_NULLPTR)
    {
        parent_->installEventFilter(this);
        setParent(parent_);

        curPos.moveCenter(parent_->mapToGlobal(container.center()));
    }
    else
    {
        curPos.moveCenter(container.center());
    }

    setGeometry(curPos);

    setWindowFlag(Qt::FramelessWindowHint);
    setWindowFlag(Qt::Window);
    setAttribute(Qt::WA_AlwaysStackOnTop, true);
    setAttribute(Qt::WA_TranslucentBackground, true);

    QObject::connect(GlobalSignal::getInstance(), &GlobalSignal::close_msg_wnd, this, &MsgWnd::event_close_wnd);
}

MsgWnd::~MsgWnd()
{
    QObject::disconnect(GlobalSignal::getInstance(), &GlobalSignal::close_msg_wnd, this, &MsgWnd::event_close_wnd);

    timer_flag_ = false;
    if (timer_->isActive()) timer_->stop();

    delete ui;
}

void MsgWnd::mousePressEvent(QMouseEvent * event)
{
    QWidget::mousePressEvent(event);
}

void MsgWnd::showEvent(QShowEvent * event)
{
    resetShowPage();

    QWidget::showEvent(event);

    resetContent();
}

void MsgWnd::closeEvent(QCloseEvent * event)
{
    g_msg_view = Q_NULLPTR;

    deleteLater();

    QWidget::closeEvent(event);
}

void MsgWnd::event_close_wnd()
{
    show_timer(false);
    close();
}

bool MsgWnd::eventFilter(QObject * watched, QEvent * event)
{
    if (qobject_cast<QWidget*>(watched) == parent_)
    {
        if (event->type() == QEvent::Resize || event->type() == QEvent::Move)
        {
            setGeometry(parent_->geometry());
            update();
        }
    }

    return QWidget::eventFilter(watched, event);
}

void MsgWnd::resetShowPage()
{
    switch (type_)
    {
    case EMsgBoxType_NormalInfo:
        ui->wnd_msg_content->setCurrentWidget(ui->normal);
        break;
    case EMsgBoxType_ShowWait:
        ui->wnd_msg_content->setCurrentWidget(ui->normal);
        break;
    case EMsgBoxType_ConfirmEraseExistSN:
    case EMsgBoxType_ConfirmDelAction:
    case EMsgBoxType_ConfirmDelSN:
        ui->wnd_msg_content->setCurrentWidget(ui->normal);
        break;
    case EMsgBoxType_ScanInputNewSN:
        ui->wnd_msg_content->setCurrentWidget(ui->page_scan_input_sn);
        break;
    case EMsgBoxType_SendMsgFail:
        ui->wnd_msg_content->setCurrentWidget(ui->page_send_code_fail);
        break;
    default:
        ui->wnd_msg_content->setCurrentWidget(ui->normal);
        break;
    }
}

void MsgWnd::resetContent(bool flag)
{
    ui->lb_normal_tip1->clear();
    ui->lb_normal_tip2->clear();
    ui->lb_normal_tip3->clear();

    showTopleftQuitBtn(false);
    show_timer(false);

    if (!flag) return;

    switch (type_) {
    case EMsgBoxType_NormalInfo:
    {
        ui->btn_sec_normal_ok->show();
        ui->btn_nor_normal_cancel->hide();

        ui->lb_normal_tip1->setVisible(!content1_.isEmpty());
        ui->lb_normal_tip2->setVisible(!content2_.isEmpty());
        ui->lb_normal_tip3->setVisible(!content3_.isEmpty());

        ui->lb_normal_tip1->setText(content1_);
        ui->lb_normal_tip2->setText(content2_);
        ui->lb_normal_tip3->setText(content3_);
    }
        break;
    case EMsgBoxType_ShowWait:
    {
        ui->btn_sec_normal_ok->hide();
        ui->btn_nor_normal_cancel->hide();

        ui->lb_normal_tip1->setVisible(!content1_.isEmpty());
        ui->lb_normal_tip2->setVisible(!content2_.isEmpty());
        ui->lb_normal_tip3->setVisible(false);

        ui->lb_normal_tip1->setText(content1_);
        ui->lb_normal_tip2->setText(content2_);

        bool isOK;
        qint32 value = content3_.toInt(&isOK);
        qint32 time = isOK ? value : QUIT_TIME;

        show_timer(true, time);
    }
        break;
    case EMsgBoxType_ConfirmEraseExistSN:
    case EMsgBoxType_ConfirmDelAction:
    case EMsgBoxType_ConfirmDelSN:
    {
        ui->lb_normal_tip1->setVisible(!content1_.isEmpty());
        ui->lb_normal_tip2->setVisible(!content2_.isEmpty());
        ui->lb_normal_tip3->setVisible(!content3_.isEmpty());

        ui->lb_normal_tip1->setText(content1_);
        ui->lb_normal_tip2->setText(content2_);
        ui->lb_normal_tip3->setText(content3_);
    }
        break;
    case EMsgBoxType_ScanInputNewSN:
    {
        ui->edt_input_info->clear();
        ui->edt_input_info->setFocus();

        ui->lb_scan_input_sn_tip1->setVisible(!content1_.isEmpty());
        ui->lb_scan_input_sn_tip2->setVisible(!content2_.isEmpty());
        ui->lb_scan_input_sn_tip3->setVisible(!content3_.isEmpty());

        ui->lb_scan_input_sn_tip1->setText(content1_);
        ui->lb_scan_input_sn_tip2->setText(content2_);
        ui->lb_scan_input_sn_tip3->setText(content3_);
    }
        break;
    case EMsgBoxType_SendMsgFail:
    {
        ui->lb_send_fail_top->setText(content1_);

        qint32 time = QUIT_TIME;
        show_timer(true, time);
    }
        break;
    default:
        break;
    }
}

void MsgWnd::showTopleftQuitBtn(bool show)
{
    ui->btn_top_left_back->setVisible(show);
}

void MsgWnd::on_btn_sec_normal_ok_clicked()
{
    if (type_ == EMsgBoxType_ConfirmEraseExistSN)
    {
        emit GlobalSignal::getInstance()->confirm_type(EUserConfirmType_EraseExistSN, true);
        return;// 由上层应用调用关闭
    }
    else if (type_ == EMsgBoxType_ConfirmDelAction)
    {
        emit GlobalSignal::getInstance()->confirm_type(EUserConfirmType_DeleteAction, true);
    }
    else if (type_ == EMsgBoxType_ConfirmDelSN)
    {
        emit GlobalSignal::getInstance()->confirm_type(EUserConfirmType_DeleteSN, true);
    }

    close();
}

void MsgWnd::on_btn_nor_normal_cancel_clicked()
{
    if (type_ == EMsgBoxType_ConfirmEraseExistSN)
    {
        emit GlobalSignal::getInstance()->confirm_type(EUserConfirmType_EraseExistSN, false);
    }

    close();
}

void MsgWnd::on_btn_nor_quit_clicked()
{
    emit GlobalSignal::getInstance()->submit_new_sn("");
//    close();// 由上层应用调用关闭
}

void MsgWnd::on_btn_sec_submit_clicked()
{
    QString input = ui->edt_input_info->text().remove(DEL_STR_BLANK);

    if (input.isEmpty()) return;

    emit GlobalSignal::getInstance()->submit_new_sn(input);

//    close();// 由上层应用调用关闭
}

void MsgWnd::on_btn_nor_skip_clicked()
{
    close();
}

void MsgWnd::on_btn_sec_re_send_clicked()
{
    close();
}

void MsgWnd::show_timer(bool show, int32_t time)
{
    if (show)
    {
        timer_->start(1000);
        timer_flag_ = true;
        timer_cnt_ = time;

        ui->lb_fetch_timer->show();
        ui->lb_fetch_timer->setText(timer_flag_ ? QString::number(timer_cnt_) : QString(""));

        connect(timer_, &QTimer::timeout, this, [&]() {

            if (!timer_flag_) return;

            if (timer_cnt_ <= 0)
            {
                timer_flag_ = false;

                if (type_ == EMsgBoxType_ShowWait)
                    emit GlobalSignal::getInstance()->wait_timeout();

//                close();// 由上层应用调用关闭
                return;
            }

            ui->lb_fetch_timer->setText(QString::number(timer_cnt_));
            timer_cnt_ -= 1;
            timer_cnt_ = timer_cnt_ > 0 ? timer_cnt_ : 0;
        });
    }
    else
    {
        if (timer_->isActive()) timer_->stop();

        ui->lb_fetch_timer->hide();
    }
}

void MsgWnd::showWnd(const EMsgBoxType type, const QString content1, QString content2, QString content3)
{
    content1_ = content1;
    content2_ = content2;
    content3_ = content3;

    type_ = type;

    resetShowPage();
    resetContent();
}
